package figure8;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import figure8.GUI.DownloadingTrackPanel;
import figure8.GUI.TrackPanel;
import figure8.Network.Client;
import figure8.Network.Message;
import figure8.Network.NetworkConnection;
import figure8.events.DownloadFinishedEvent;
import figure8.events.DownloadProgressListener;
import figure8.events.DownloadProgressedEvent;
import figure8.events.NetworkDisconnectEvent;
import figure8.events.NetworkEventListener;
import figure8.events.NetworkMessageEvent;
import figure8.events.TrackChangeListener;

public class DownloadingTrack implements Track {
	protected int size;
	protected int downloaded;
	
	protected Track track;
	protected Track.Type type;
	
	protected Project project;
	
	protected List<DownloadProgressListener> downloadlisteners;
	
	protected Client client;
	
	public static DownloadingTrack deserialize(Project project, String trackstring, Client client) {
		String parts[] = trackstring.split(" ", 2);
		
		Track track = null;
		Track.Type type = Track.Type.valueOf(parts[0]);
		
		switch (type) {
		case DRUM:
			track = DrumMachineTrack.fromString(project, parts[1]);
			
			break;
		case WAV:
			track = WAVTrack.fromString(project, parts[1]);
			break;
		case MIDI:
			track = MIDITrack.fromString(project, parts[1]);
			break;
		case EFFECT:
			track = EffectTrack.fromString(parts[1]);
			break;
		}
		
		if (track == null)
			System.out.println("Should not be null " + type);
		
		return new DownloadingTrack(project, track, type, client);
	}
	
	public DownloadingTrack(Project project, Track track, Track.Type type, Client client) {
		this.project = project;
		
		this.track = track;
		this.type = type;
		
		this.client = client;
		
		this.size = size;
		this.downloaded = 0;
		
		this.downloadlisteners = new LinkedList<DownloadProgressListener>();
	}
	
	@Override
	public void play() {
		System.err.println("Could not play unfinished track.");
	}

	@Override
	public void pause() {
		System.err.println("Unfinished track is not playing.");
	}

	@Override
	public void stop() {
		System.err.println("Unfinished track is not playing.");
	}
	
	public int getSize() {
		return this.size;
	}
	
	@Override
	public TrackPanel makeTrackPanel(Controller controller) {
		return new DownloadingTrackPanel(controller, this);
	}

	@Override
	public File getFile() {
		return null;
	}

	@Override
	public Boolean[][] getDrumMachine() {
		return null;
	}

	@Override
	public void send(NetworkConnection client, Client exclude) {
		System.out.println("Not sending unfinished track " + this.getName() + ".");
	}

	@Override
	public String serializeMetadata() {
		return null;
	}

	@Override
	public Type getType() {
		return this.track.getType();
	}

	@Override
	public String deserializeMetadata(String metadata) {
		return "";
	}

	@Override
	public int getID() {
		if (this.track == null)
			System.out.println("This is for some reason null");
		
		return this.track.getID();
	}

	@Override
	public void close() {
		this.track.close();
	}

	@Override
	public String getName() {
		return "Unfinished download of \"" + this.track.getName() + "\"";
	}

	@Override
	public void setName(String name) {
		this.track.setName(name);
	}

	@Override
	public boolean getMuted() {
		return this.track.getMuted();
	}

	@Override
	public void setMuted(boolean muted) {
		this.track.setMuted(muted);
	}
	
	@Override
	public boolean getSoloing() {
		return this.track.getSoloing();
	}

	@Override
	public void setSoloing(boolean soloing) {
		this.track.setSoloing(soloing);
	}

	@Override
	public float getVolume() {
		return this.track.getVolume();
	}	

	@Override
	public void setVolume(float volume) {
		this.track.setVolume(volume);
	}
	
	@Override
	public float getPan() {
		return this.track.getPan();
	}	

	@Override
	public void setPan(float pan) {
		this.track.setPan(pan);
	}
	
	public void finalize() {
		if (this.ready()) {
			this.track.finalize();
			this.project.deleteTrack(this, this.client);
			this.project.addTrack(this.track, this.client);
			System.out.println("Finished getting track \"" + this.track.getName() + "\"");
		}
	}

	@Override
	public boolean ready() {
		return this.track.ready();
	}

	@Override
	public void addChangeListener(TrackChangeListener listener) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeChangeListener(TrackChangeListener listener) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void sendMeta(NetworkConnection client) {
		
	}
	
	@Override
	public void updateMeta(String data) {
		this.track.updateMeta(data);
	}

	@Override
	public void sendFile(NetworkConnection client, Client exclude) {
		
	}

	@Override
	public void filePart(String data) {
		this.track.filePart(data);
		this.fireDownloadProgressedEvent(this.track, this.track.percentage());
		
		if (this.track.ready()) {
			this.fireDownloadFinishedEvent(this.track);
			this.finalize();
		}
	}

	@Override
	public float percentage() {
		// TODO Auto-generated method stub
		return this.track.percentage();
	}
	
	public void addDownloadListener(DownloadProgressListener listener) {
		this.downloadlisteners.add(listener);
	}

	public void removeDownloadListener(DownloadProgressListener listener) {
		this.downloadlisteners.remove(listener);
	}
	
	protected void fireDownloadFinishedEvent(Track track) {
		for (DownloadProgressListener listener : this.downloadlisteners) {
			listener.downloadFinished(new DownloadFinishedEvent(this, this.track));
		}
	}

	protected void fireDownloadProgressedEvent(Track track, float progress) {
		for (DownloadProgressListener listener : this.downloadlisteners) {
			listener.downloadProgressed(new DownloadProgressedEvent(this, this.track, progress));
		}
	}

	@Override
	public boolean isDrum() {
		// TODO Auto-generated method stub
		return false;
	}

}
